package com.yss.sofa.ide.builder.dbscript.ui.wizard;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Text;

import com.yss.sofa.ide.builder.dbscript.model.ScriptInfo;
import com.yss.sofa.ide.builder.dbscript.ui.internal.Config;
import com.yss.sofa.ide.ui.wizard.BaseWizardPage;

public class NewDBManagerProjectWizardPage extends BaseWizardPage {

  public static final String ID = "NewDBManagerProjectWizardPage";

  private ScriptInfo info;
  private boolean isFirst;
  // private Text pathText;
  private Combo sourceCombo;
  private List list;
  private Text projectNameText;
  private Text createTableText;
  private Text dropTableText;
  private Text insertDataText;
  private String[] items = new String[] { "DB2", "MSSQL", "MYSQL", "ORACLE" };

  private Button upperCaseButton;

  public NewDBManagerProjectWizardPage(ScriptInfo info, boolean isFirst) {
    super(ID);
    info.setTargetTypes(items);
    this.info = info;
    this.isFirst = isFirst;
    setTitle(Messages.NewDBManagerProjectWizardPage_TITLE1);
    setDescription(Messages.NewDBManagerProjectWizardPage_DESC1);
  }

  @Override
  public void createControl(Composite parent) {
    Composite container = new Composite(parent, SWT.NONE);
    container.setLayout(new GridLayout(1, false));
    createGUI(container);
    addListener();
    bindData();
    setControl(container);
    setPageComplete(validatePage());
    Dialog.applyDialogFont(container);
  }

  private void createGUI(Composite parent) {
    Composite composite = new Composite(parent, SWT.NONE);
    GridData data = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
    data.heightHint = 350;
    composite.setLayoutData(data);
    composite.setLayout(new GridLayout(3, false));

    Label projectNameLabel = new Label(composite, SWT.NONE);
    projectNameLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
    projectNameLabel.setText(Messages.NewDBManagerProjectWizardPage_PROJECT_NAME);

    this.projectNameText = new Text(composite, SWT.BORDER);
    this.projectNameText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

    upperCaseButton = new Button(composite, SWT.CHECK);
    upperCaseButton.setSelection(true);
    upperCaseButton.setText(Messages.NewDBManagerProjectWizardPage_btnCheckButton_text);

    // Label dataLocationLabel = new Label(composite, SWT.NONE);
    // dataLocationLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
    // dataLocationLabel.setText(Messages.NewDBManagerProjectWizardPage_DATA_LOCATION);

    // this.pathText = new Text(composite, SWT.BORDER | SWT.READ_ONLY);
    // this.pathText.setText(getMappingFile());
    // this.pathText.setEnabled(false);
    // this.pathText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
    // new Label(composite, SWT.NONE);

    Label sourceLabel = new Label(composite, SWT.NONE);
    sourceLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
    sourceLabel.setText(Messages.NewDBManagerProjectWizardPage_SOURCE);

    this.sourceCombo = new Combo(composite, SWT.NONE | SWT.READ_ONLY);
    this.sourceCombo.setItems(new String[] { "ORACLE" }); //$NON-NLS-1$
    this.sourceCombo.select(0);
    this.sourceCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));

    Label label_1 = new Label(composite, SWT.NONE);
    label_1.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false, 1, 1));
    label_1.setText(Messages.NewDBManagerProjectWizardPage_TARGET);

    this.list = new List(composite, SWT.BORDER | SWT.MULTI);
    this.list.setItems(items); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    this.list.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1));

    Label createTableLabel = new Label(composite, SWT.NONE);
    createTableLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
    createTableLabel.setText(Messages.NewDBManagerProjectWizardPage_CREATE_FILE_NAME);

    this.createTableText = new Text(composite, SWT.BORDER | SWT.READ_ONLY);
    this.createTableText.setText(Config.CREATE);
    this.createTableText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));

    Label dropTableLabel = new Label(composite, SWT.NONE);
    dropTableLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
    dropTableLabel.setText(Messages.NewDBManagerProjectWizardPage_DROP_FILE_NAME);

    this.dropTableText = new Text(composite, SWT.BORDER | SWT.READ_ONLY);
    this.dropTableText.setText(Config.DROP);
    this.dropTableText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));

    Label insertDataLabel = new Label(composite, SWT.NONE);
    insertDataLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
    insertDataLabel.setText(Messages.NewDBManagerProjectWizardPage_INSERT_FILE_NAME);

    this.insertDataText = new Text(composite, SWT.BORDER | SWT.READ_ONLY);
    this.insertDataText.setText(Config.INSERT);
    this.insertDataText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));

    setTitle(Messages.NewDBManagerProjectWizardPage_TITLE);
    this.setMessage(Messages.NewDBManagerProjectWizardPage_DESC);
    setControl(composite);
  }

  private void addListener() {
    upperCaseButton.addSelectionListener(new SelectionAdapter() {
      @Override
      public void widgetSelected(SelectionEvent e) {
        if (upperCaseButton.getSelection()) {
          String upperCase = projectNameText.getText().toUpperCase();
          projectNameText.setText(upperCase);
        }
      }
    });

    dataCheckButtonAddListener();
    dataBrowsButtonAddListener();
    projectNameAddModifyListener();
    sourceComboAddListener();
    listAddListener();
  }

  private void listAddListener() {
    this.list.addSelectionListener(new SelectionAdapter() {
      @Override
      public void widgetSelected(SelectionEvent e) {
        setPageComplete(validatePage());
        IWizardPage page = getNextPage().getNextPage();
        if (page.getControl() != null) {
          page.dispose();
        }
      }
    });
  }

  private void sourceComboAddListener() {
    this.sourceCombo.addSelectionListener(new SelectionAdapter() {
      @Override
      public void widgetSelected(SelectionEvent e) {
        setPageComplete(validatePage());
      }
    });
  }

  private void projectNameAddModifyListener() {
    this.projectNameText.addVerifyListener(new VerifyListener() {

      @Override
      public void verifyText(VerifyEvent e) {
        if (upperCaseButton.getSelection()) {
          e.text = e.text.toUpperCase();
        }
      }
    });

    projectNameText.addModifyListener(new ModifyListener() {
      @Override
      public void modifyText(ModifyEvent e) {
        modifyPage();
        setPageComplete(validatePage());
      }
    });
  }

  private void dataBrowsButtonAddListener() {
  }

  private void dataCheckButtonAddListener() {
  }

  private void bindData() {
    this.list.setSelection(this.info.getTargetTypes());
    if (!this.isFirst) {
      this.projectNameText.setText(this.info.getProjectName());
      this.sourceCombo.setText(this.info.getSourceType());
      this.projectNameText.setEnabled(false);
      modifyPage();
    }
  }

  public boolean validate() {
    if (this.isFirst) {
      return projectNameIsExist() && targetTypeIsEmpty();
    }
    return targetTypeIsEmpty();
  }

  private boolean targetTypeIsEmpty() {
    if (this.list.getSelection().length > 0) {
      setErrorMessage(null);
      return true;
    } else {
      setErrorMessage(Messages.NewDBManagerProjectWizardPage_TARGET_ERROR_MESSAGE);
      return false;
    }
  }

  private boolean projectNameIsExist() {
    if (projectNameText.getText().isEmpty()) {
      setErrorMessage(Messages.NewDBManagerProjectWizardPage_PROJECT_NAME_ERROR_MESSAGE);
      return false;
    }
    CreateDBManagerWizard wizard = (CreateDBManagerWizard) getWizard();
    IProject project = wizard.getProject();
    IFile file = project.getFolder(Config.DATA).getFile(projectNameText.getText() + Config.SCRIPTE);

    if (file.exists()) {
      setErrorMessage(Messages.NewDBManagerProjectWizardPage_PROJECT_EXIST_ERROR);
      return false;
    } else {
      setErrorMessage(null);
      return true;
    }
  }

  @Override
  public Object getPageData() {
    info.setTargetTypes(getTargetNames());
    info.setSourceType(getSourceNames());
    info.setProjectName(getProjectName());
    info.setCreateFileName(createTableText.getText().trim());
    info.setInsertFileName(insertDataText.getText().trim());
    info.setDropFileName(dropTableText.getText().trim());
    return info;
  }

  public String getSourceNames() {
    return this.sourceCombo.getText();
  }

  public String[] getTargetNames() {
    return this.list.getSelection();
  }

  private String getMappingFile() {
    String path = Platform.getInstanceLocation().getURL().getPath();
    if (path.startsWith(Messages.NewDBManagerProjectWizardPage_SEPARATOR)) {
      path = path.substring(1);
    }
    return path;
  }

  private void modifyPage() {
    // this.projectPathText.setText(getMappingFile() + this.projectNameText.getText());
    // this.pathText.setText(getDataPath());

    this.createTableText.setText(getSqlFolderName(Config.CREATE));
    this.insertDataText.setText(getSqlFolderName(Config.INSERT));
    this.dropTableText.setText(getSqlFolderName(Config.DROP));
  }

  public String getSqlFolderName(String fileName) {
    return this.projectNameText.getText().isEmpty() ? fileName : this.projectNameText.getText() + fileName;
  }

  private String getDataPath() {
    String data = "/data";
    return this.projectNameText.getText().isEmpty() ? getMappingFile() : getMappingFile()
        + this.projectNameText.getText() + data;
  }

  public String getProjectName() {
    return this.projectNameText.getText();
  }

  // public String getCreateDataPath() {
  // return this.pathText.getText();
  // }
}
